<template>
  <div :name="amisName" >Loading...</div>
</template>


<script setup lang="ts">

// 页面切换的时候，会触发该按钮的 click 事件
import {string} from "vue-types";

const AMIS_FORM_ACTIVED_BUT = "u:amisFormActivedBut"
// 外部获取amis内部 form 组件的表单值
const AMIS_GET_FORM_VALUE_FORM_ID = "u:amisGetFormValueFormId"
const AMIS_UNMOUNTED_BUTTON_ID = "u:amisUnmountedButtonId"



import {useTagsViewStore} from "@/store/modules/tagsView";

console.log("AmisFormComponent.vue。。。。")

import {watch, ref, PropType} from "vue"
import {ElMessage, ElMessageBox, ElNotification} from 'element-plus'
import { useI18n } from '../../hooks/web/useI18n'
import request from '@/config/axios/amisAxios'
import copy from 'copy-to-clipboard'
import { generateUUID } from '@/utils'
import * as FormApi from "@/api/bpm/form";
import * as AmisFormContext from "@/components/AmisFormComponent/amisFormContext";
import {FieldPermissionType} from "@/components/SimpleProcessDesignerV2/src/consts";
const message = useMessage() // 消息弹窗
const { delView } = useTagsViewStore() // 视图操作


defineOptions({ name: 'AmisFormComponent' })

// window.enableAMISDebug = true;

const props = defineProps({
  formContext: {
    type: Object as PropType<AmisFormContext>,
    required: true
  },
  formData: {
    type: Object ,
    required: false,
    default: ()=>{
      return {};
    }
  },
  hideAmisButton: {
    type: Boolean ,
    required: false,
    default: false,
  },
  readOnlyAmis: {
    type: Boolean ,
    required: false,
    default: false,
  },
  fieldsPermission: {
    type: Object ,
    required: false,
    default: ()=>{
      return {};
    }
  }
})


function loadScript(src, callback) {
  const script = document.createElement("script");
  script.setAttribute("type", "text/javascript");
  script.setAttribute("src", src);
  script.onload = () => callback();
  script.onerror = () => callback(new Error(`Failed to load ${src}`));
  document.body.appendChild(script);
}

function loadStyles(styles) {
  for (const path of styles) {
    const style = document.createElement("link");
    style.setAttribute("rel", "stylesheet");
    style.setAttribute("type", "text/css");
    style.setAttribute("href", path);
    document.head.appendChild(style);
  }
}

function loadSDK() {
  return new Promise((resolve, reject) => {
    if (window.amisRequire) {
      resolve();
      return;
    }
    loadStyles([
      "/amis/sdk/sdk.css",
      "/amis/sdk/helper.css",
      "/amis/sdk/iconfont.css",
    ]);
    loadScript("/amis/sdk/sdk.js", (err) => {
      if (err) {
        reject(err);
        return;
      }
      resolve();
    });
  });
}

// window.enableAMISDebug = true

const loading = ref(false)
const unmounted = ref(false)
const amisInstance = ref()
const formJson = ref({})
const amisName = ref("amisName"+ generateUUID())
const route = useRouter() // 路由信息
const { t } = useI18n()

const getFormById = async (amisFormId) => {
  let formDate = await FormApi.getForm(amisFormId)
  const schema = JSON.parse(formDate.conf?formDate.conf:"")
  console.log("schema",schema)
  return schema ;
}

onMounted(async () => {
  console.log("AmisFormComponent.vue   onMounted...")

  if(!!props.formContext.amisFormId){
    let amisJson = await getFormById(props.formContext.amisFormId)

    // 只读
    if(props.readOnlyAmis){
      formReadOnly(amisJson)
    }
    // 隐藏Amis的按钮
    if(props.readOnlyAmis || props.hideAmisButton){
      hidebut(amisJson)
    }
    if(props.fieldsPermission && Object.keys(props.fieldsPermission).length > 0){
      setFieldsPermission(amisJson,props.fieldsPermission)
    }
    formJson.value = amisJson
  }else {
    throw new Error("Amis传入参数错误")
  }

  try {
    loading.value = true;
    await loadSDK();
  } finally {
    loading.value = false;
  }
  if (unmounted.value) {
    return;
  }
  console.log("formJson",formJson.value)

  console.log("route",route)

  // @ts-ignore
  const amis = amisRequire('amis/embed');
  const { normalizeLink } = amisRequire("amis");

  watch(()=> formJson.value, (data)=>{
      onRendering(data)
    },
    {immediate: true,deep: true}
  )

  function onRendering(data:any){
    // let amisScoped = amis.embed('#amisid', data);
    console.log("props.formData",props.formData)
    console.log("props.formContext",props.formContext)
    let theme = 'cxd'
    amisInstance.value = amis.embed(
      "[name='"+amisName.value+"']",
      data,
      {
        updateLocation: (to, replace) => {},
        // 赋予 amis 顶层数据域的值
        data: {
          ...props.formData
        },
        // context 数据，无论哪层都可以使用到这个里面的数据
        context: {
          ...props.formContext
        }
      },
      {
        // 下面三个接口必须实现
        fetcher: ({
                    url, // 接口地址
                    method, // 请求方法 get、post、put、delete
                    data, // 请求数据
                    responseType,
                    config, // 其他配置
                    headers ,// 请求头
                    updateLocation
                  }) => {
          config = config || {};
          config.withCredentials = true;

          // 设置接口地址
          // config.baseURL = import.meta.env.VITE_APP_BASE_API;

          responseType && (config.responseType = responseType);

          // if (config.cancelExecutor) {
          //     config.cancelToken = new (axios).CancelToken(
          //         config.cancelExecutor
          //     );
          // }

          config.headers = headers || {};

          // 设置token
          // const isToken = (config.headers || {}).isToken === false
          // if (getToken() && !isToken) {
          //     config.headers['token'] = getToken()
          // }

          // responseType: "blob"
          console.log(url, data, config,'url, data, config')
          if(config["responseType"] == "blob"){
            method = "download" ;
          }

          if (method !== 'post' && method !== 'put' && method !== 'patch') {
            if (data) {
              config.params = data;
            }

            // return (axios )[method](url, config);
            return (request )[method]({url, config});
          } else if (data && data instanceof FormData) {
            config.headers = config.headers || {};
            config.headers['Content-Type'] = 'multipart/form-data';
            method = "upload" ;
          } else if (data && typeof data !== 'string' && !(data instanceof Blob) && !(data instanceof ArrayBuffer)) {
            data = JSON.stringify(data);
            config.headers = config.headers || {};
            config.headers['Content-Type'] = 'application/json';
          }

          // return (axios )[method](url, data, config);
          return (request )[method]({url, data, config});
        },
        // isCancel: (value) => (axios ).isCancel(value),
        copy: content => {
          copy(content);
          ElMessage.success('内容已复制到粘贴板');
        },
        jumpTo: (to, action) => {
          console.log('jumpTo: (to, action)',to, action)
          if (to === "goBack") {
            // 关闭当前 Tab
            delView(unref(route.currentRoute))
            // 退回上个路由
            return route.go(-1);
          }

          // 路由模式改编为：createWebHashHistory 所以注释掉
          // to = normalizeLink(to, location);

          if (action?.actionType === "url") {
            action.blank === false ? route.push(to) : window.open(to);
            return;
          }

          // 主要是支持 nav 中的跳转
          if (action && to && action.target) {
            window.open(to, action.target);
            return;
          }

          if (/^https?:\/\//.test(to)) {
            window.location.replace(to);
          } else {
            route.push(to);
          }
        },
        updateLocation: (location, replace) => {
          console.log('updateLocation: (location, replace)',location, replace)
          if (location === "goBack") {
            return route.go(-1);
          }

          // 此处不能更新路由，否则tab页面会不断刷新
          // location = normalizeLink(location);
          // replace ? route.replace(location) : route.replace(location);
        },
        // 用来配置弹窗等组件的挂载位置
        // todo amis对象的作用域是全局的，所以这边不能这么写
        // getModalContainer: () => {
        //   console.log("getModalContainer....")
        //   return document.getElementsByName(amisName.value)[0]
        // },
        // 用来实现通知
        notify: (type, msg) => {
          console.log("notify....",type, msg)
          if(type == "error"){
            message.notifyError(msg)
          }
          else if(type == "info"){
            message.notify(msg)
          }
          else if(type == "success"){
            message.notifySuccess(msg)
          }
          else if(type == "warning"){
            message.notifyWarning(msg)
          }
        },
        // 用来实现提示
        alert: content => {
          console.log("alert....",content)
          return ElMessageBox.alert(content, t('common.confirmTitle'))
        },
        // 用来实现确认框。
        confirm: content => {
          console.log("confirm....",content)
          return message.confirm(content)
        },
        // 在amis里面广播调用外部
        // https://aisuda.bce.baidu.com/amis/zh-CN/docs/extend/ui-library#%E7%9B%91%E5%90%AC%E5%B9%BF%E6%92%AD%E4%BA%8B%E4%BB%B6
        onBroadcast: (type, rawEvent, data) => {
          console.log('onBroadcast...',type, rawEvent, data);
        },
        // Toast提示弹出位置，默认为'top-center'
        toastPosition: 'center',
        theme,
        // 关闭 移动端原生 UI，防止WPS中以移动端显示
        useMobileUI: false
      }
    )
  }
})
onUnmounted(async () => {
  console.log("AmisFormComponent.vue   onUnmounted...")
  unmounted.value = true;
  amisInstance.value.unmount();
})
onActivated(()=>{
  console.log("AmisFormComponent...onActivated...")
  // 页面被激活，需要调用内部
  amisFormActived();
})

const amisFormActived = function (){
  amisInstance.value?.getComponentById(AMIS_FORM_ACTIVED_BUT)?.doAction({
    actionType: "click",
  })
}
/**
 * 获取表单数据
 */
const getFormDate = function (){
  console.log("getFormDate...")
  return amisInstance.value?.getComponentById(AMIS_GET_FORM_VALUE_FORM_ID)?.getData() ;
}
/**
 * 设置表单数据
 */
const setData = function (value: any, replace?: boolean){
  console.log("setData...")
  return amisInstance.value?.getComponentById(AMIS_GET_FORM_VALUE_FORM_ID)?.setData(value,replace) ;
}
/**
 * 触发表单校验，返回boolean
 */
const valiDate = function (){
  console.log("valiDate...")
  return amisInstance.value?.getComponentById(AMIS_GET_FORM_VALUE_FORM_ID)?.validate() ;
}
const onAmisUnmounted = function (){
  // 调用挂载的事件
  console.log("onAmisUnmounted...")
  amisInstance.value?.doAction({
    "actionType": "click",
    "componentId": AMIS_UNMOUNTED_BUTTON_ID
  })
}

const hidebut = function(amisJson: any) {
  // 递归遍历 JSON 对象，查找并修改 actions 节点
  function traverseAndModify(obj: any): void {
    if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
      // 如果当前对象有 actions 属性且是数组
      if (obj.actions && Array.isArray(obj.actions)) {
        // 为 actions 数组中的每个对象设置 visible=false
        obj.actions.forEach((action: any) => {
          if (action && typeof action === 'object') {
            action.visible = false;
          }
        });
        return
      }

      // 如果当前对象的 type 为 button 或 reset，也设置 visible=false
      if (obj.type === 'button' || obj.type === 'reset') {
        obj.visible = false;
        return;
      }

      // 递归处理所有子属性
      Object.keys(obj).forEach(key => {
        if (obj[key] && typeof obj[key] === 'object') {
          traverseAndModify(obj[key]);
        }
      });
    } else if (obj && typeof obj === 'object' && Array.isArray(obj)) {
      // 如果是数组，遍历数组中的每个元素
      obj.forEach(item => {
        traverseAndModify(item);
      });
    }
  }

  // 开始遍历并修改
  traverseAndModify(amisJson);
}

const formReadOnly = function(amisJson: any) {
  // 递归遍历 JSON 对象，查找 type=form 的节点
  function traverseAndModify(obj: any): void {
    if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
      // 如果当前对象的 type 为 form，设置 static=true，并且不再继续遍历子属性
      if (obj.type === 'form' || obj.type === 'input-table') {
        obj.static = true;
        delete obj.staticOn;
        // 注意：这里不继续递归子属性，直接返回
      }

      // 递归处理所有子属性
      Object.keys(obj).forEach(key => {
        if (obj[key] && typeof obj[key] === 'object') {
          traverseAndModify(obj[key]);
        }
      });
    } else if (obj && typeof obj === 'object' && Array.isArray(obj)) {
      // 如果是数组，遍历数组中的每个元素
      obj.forEach(item => {
        traverseAndModify(item);
      });
    }
  }

  // 开始遍历并修改
  traverseAndModify(amisJson);
}

const setFieldsPermission = function(amisJson: any, fieldsPermission: any) {
  // 直接使用fieldsPermission对象，格式: { fieldName: permissionValue }
  const permissionMap = fieldsPermission

  // 递归遍历amisJson对象
  function traverseAndModify(obj: any): void {
    if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
      // 检查对象是否有name属性，且该name在权限映射中
      if (obj.name && permissionMap.hasOwnProperty(obj.name)) {
        const permissionValue = permissionMap[obj.name]

        // 根据权限值设置属性
        switch (permissionValue) {
          case FieldPermissionType.READ: // 只读
            obj.static = true
            delete obj.staticOn;
            break
          case FieldPermissionType.NONE: // 隐藏
            obj.visible = false
            break
          default:
            break
        }
      }

      // 递归处理所有子属性
      Object.keys(obj).forEach(key => {
        if (obj[key] && typeof obj[key] === 'object') {
          traverseAndModify(obj[key])
        }
      })
    } else if (obj && typeof obj === 'object' && Array.isArray(obj)) {
      // 如果是数组，遍历数组中的每个元素
      obj.forEach(item => {
        traverseAndModify(item)
      })
    }
  }

  // 开始遍历并修改
  traverseAndModify(amisJson)
}


// 暴露方法，提供给父组件
defineExpose({getFormDate,setData,valiDate,onAmisUnmounted})


</script>

